/*
 * Aircraft.h
 *
 *  Created on: Apr 28, 2011
 *      Author: tflanzer
 */

#ifndef AIRCRAFT_H_
#define AIRCRAFT_H_

#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <fstream>
#include "Matrix.h"
#include "Vector1D.h"
#include "execStruct.h"
#include "ElectricPropulsion.h"
#include "SeaLevelAtmosphere.h"

#define NELEMENTS 3
#define MAXGEOMSEGS 10
#define MAXCOLELEMS 50
#define MAXELEM MAXCOLELEMS*NELEMENTS
#define AIRCRAFT_TYPE "EASYGLIDERPRO"
#define PI 3.141592653589793

struct acStruct {
	int cgp;
	double CDp, mass, I[9], cg[3], CLmax, CLmin, Sref, bref, cref, Ne, Ntot, Cm0,
		maxThrust;
	double AICinv[MAXELEM*MAXELEM], udw[MAXELEM*MAXELEM],
		vdw[MAXELEM*MAXELEM], wdw[MAXELEM*MAXELEM],
		macp[MAXELEM][3], maqc[MAXELEM][3], pnorm[MAXELEM][3],
		di[MAXELEM], tw[MAXELEM], plt[MAXELEM], pa[MAXELEM],
		cs[MAXELEM], gvec[MAXELEM][3], qcb[MAXELEM][3],
		cp[MAXELEM][3];
};

struct geomElement {
	int N, Ns, mirror;
	double yle[MAXGEOMSEGS], zle[MAXGEOMSEGS], chord[MAXGEOMSEGS+1],
		   sweep[MAXGEOMSEGS], twist[MAXGEOMSEGS+1], apex[3], cs[MAXGEOMSEGS+1];
};

struct geomTot {
	geomElement gelem[NELEMENTS];
};

struct colElem {
	int N;
	//double *cptw, *qcsux, *nor;
	double qc[2*MAXCOLELEMS+1][3];
	double te[2*MAXCOLELEMS+1][3];
	double cp[2*MAXCOLELEMS][3];
	double ch[2*MAXCOLELEMS+1];
	double tw[2*MAXCOLELEMS+1];
	double di[2*MAXCOLELEMS+1];
	double cs[2*MAXCOLELEMS+1];
	double dihedral[MAXGEOMSEGS];
	double ds[2*MAXCOLELEMS];
	double cptw[2*MAXCOLELEMS];
	double qcusx[2*MAXCOLELEMS+1];
	double nor[2*MAXCOLELEMS][3];
};

struct colTot {
	colElem celem[NELEMENTS];
};

struct enStruct {
	double Vr;
};

struct aeroStruct {
	double F[3], M[3];
	double CD, CY, CL, Cl, Cm, Cn;
};

void MassPropInit(acStruct &a);
void AirfoilPropInit(acStruct &a);
void downwash(acStruct &ac, colTot &ct);
void envInit(enStruct &en);

class Aircraft {
public:
	acStruct ac;
	enStruct en;
	aeroStruct as;

	double SD[6*9];

	SeaLevelAtmosphere *atm;
	ElectricPropulsion *propulsion;

	void geomSetup(geomTot &gt);
	void latticeSetup(colTot &ct, geomTot &gt);
	void acInit(acStruct &ac, colTot &ct);
	void getProcessModelState(double *statein, double *stateout, double *ctrl,
			double dt);
	void getMeasModelState(double *statein, double *stateout, double *ctrl,
			double dt, bool flag);
	void aeroSolverVLM(double *state, double *ctrl);
	void aeroSolverLinear(double *state, double *ctrl);
	void envwinds(double *x, double *dcm, double *we);
	void loadSDMatrix();
	Aircraft();
	virtual ~Aircraft();

private:
	void crossprod(double a1, double a2, double a3, double b1,
			double b2, double b3, double *c);
	void controlSurfaces(int Ntot, double ail, double ele, double rud, double flp,
			double *pnorm, double *cs, double *tw, double *di);
	void bodyTOwind(double alpha, double beta, double *dcm);
	void checkCLmax(int Ntot, double *dcm, double *Fn, double rho, double *wt, double *pa, double *cs,
		double CLmax, double CLmin, double flp);
	void body2inertial(double psi,double th, double phi, double *dcm);
};

#endif /* AIRCRAFT_H_ */
